package com.micro.ai.gateway.util;

import com.micro.ai.commons.domain.ApiResponse;
import com.micro.ai.commons.util.JsonUtils;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

/**
 * 响应工具类
 * 提供统一的JSON响应处理方法
 * 
 * @author micro-ai
 * @since 0.0.1
 */
public class ResponseUtils {
    
    /**
     * 写入JSON响应
     * 
     * @param exchange ServerWebExchange
     * @param status HTTP状态码
     * @param code 业务错误码
     * @param message 错误消息
     * @return Mono<Void>
     */
    public static Mono<Void> writeJsonResponse(
            ServerWebExchange exchange,
            HttpStatus status,
            String code,
            String message) {
        
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(status);
        response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        
        ApiResponse<Void> apiResponse = ApiResponse.error(code, message);
        String body = JsonUtils.toJson(apiResponse);
        
        DataBuffer buffer = response.bufferFactory().wrap(
            body.getBytes(StandardCharsets.UTF_8)
        );
        
        return response.writeWith(Mono.just(buffer));
    }
    
    /**
     * 401 Unauthorized - 未认证
     * 
     * @param exchange ServerWebExchange
     * @param code 业务错误码
     * @param message 错误消息
     * @return Mono<Void>
     */
    public static Mono<Void> unauthorized(ServerWebExchange exchange, String code, String message) {
        return writeJsonResponse(exchange, HttpStatus.UNAUTHORIZED, code, message);
    }
    
    /**
     * 403 Forbidden - 无权限或访问被拒绝
     * 
     * @param exchange ServerWebExchange
     * @param code 业务错误码
     * @param message 错误消息
     * @return Mono<Void>
     */
    public static Mono<Void> forbidden(ServerWebExchange exchange, String code, String message) {
        return writeJsonResponse(exchange, HttpStatus.FORBIDDEN, code, message);
    }
    
    /**
     * 429 Too Many Requests - 请求过于频繁（限流）
     * 
     * @param exchange ServerWebExchange
     * @param code 业务错误码
     * @param message 错误消息
     * @return Mono<Void>
     */
    public static Mono<Void> tooManyRequests(ServerWebExchange exchange, String code, String message) {
        return writeJsonResponse(exchange, HttpStatus.TOO_MANY_REQUESTS, code, message);
    }
    
    /**
     * 500 Internal Server Error - 服务器内部错误
     * 
     * @param exchange ServerWebExchange
     * @param code 业务错误码
     * @param message 错误消息
     * @return Mono<Void>
     */
    public static Mono<Void> internalServerError(ServerWebExchange exchange, String code, String message) {
        return writeJsonResponse(exchange, HttpStatus.INTERNAL_SERVER_ERROR, code, message);
    }
    
    /**
     * 503 Service Unavailable - 服务不可用
     * 
     * @param exchange ServerWebExchange
     * @param code 业务错误码
     * @param message 错误消息
     * @return Mono<Void>
     */
    public static Mono<Void> serviceUnavailable(ServerWebExchange exchange, String code, String message) {
        return writeJsonResponse(exchange, HttpStatus.SERVICE_UNAVAILABLE, code, message);
    }
    
    /**
     * 504 Gateway Timeout - 网关超时
     * 
     * @param exchange ServerWebExchange
     * @param code 业务错误码
     * @param message 错误消息
     * @return Mono<Void>
     */
    public static Mono<Void> gatewayTimeout(ServerWebExchange exchange, String code, String message) {
        return writeJsonResponse(exchange, HttpStatus.GATEWAY_TIMEOUT, code, message);
    }
    
    /**
     * 写入成功响应
     * 
     * @param exchange ServerWebExchange
     * @param data 响应数据
     * @return Mono<Void>
     */
    public static <T> Mono<Void> writeSuccessResponse(ServerWebExchange exchange, T data) {
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.OK);
        response.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
        
        ApiResponse<T> apiResponse = ApiResponse.success(data);
        String body = JsonUtils.toJson(apiResponse);
        
        DataBuffer buffer = response.bufferFactory().wrap(
            body.getBytes(StandardCharsets.UTF_8)
        );
        
        return response.writeWith(Mono.just(buffer));
    }
}

